You can use whatever steering method you like. The navigation stack outputs velocity commands for the robot base to follow. You will need to make a node to use the inverse kinematic equations to determine how to control the robot. To get odom you do the reverse; get the encoder counts from the wheels and use the kinematic equations to determine the velocities of the robot. This is easiest with a differential drive, but with some work you should be able to get it working with Ackerman steering.

[EDIT]

1 - You need to populate nav_msgs/Odometry messages. The link shows what information is required. Basically, the message requires a time stamp, frame id, the velocities (linear and rotational) of the robot, and the position (x, y, z) of the robot relative to its start pose.

2 - A tutorial on how to generate the odometry messages can be found on the wiki. The tutorial puts in hard coded velocity values simulating the robot going in a circle. To calculate the actual values you need to use the kinematic equations of your robot. You will need some way of knowing what angles your wheels are at and at what speed they are rotating. You then sub these values into the kinematic equations to determine the the robot's overall velocities. Summing these velocities over a series of time steps provides the robot's pose. Here is a link to an odom node I wrote a while ago for an omnidirectional robot.

3 - If you use the navigation stack with the move_base node, move_base will publish geometry_msgs/Twist messages, which contain linear and rotational velocities for the robot. Your arduino node will have to subscribe to that topic (default is cmd_vel), use the inverse kinematic equations to determine what speeds and angles the wheels need to be at to achieve the commands sent by move_base. The Arduino then sends this to the motors and actuators.